#pragma once
#include"Rpcregistry.hpp"
#include"Rpc_Router.hpp"
#include"../Client/Rpc_client.hpp"
#include"Rpc_pushlish.hpp"

namespace zgwrpc
{
    namespace server
    {
        
        //服务注册中心服务端
        class Rpc_Registry
        {
        public:
        Rpc_Registry(int port):_pd_manager(make_shared<PDManger>()),_dispatcher(make_shared<Dispatcher>())
        ,_router(make_shared<Rpc_Router>())
        {
            auto message_callback=std::bind(&PDManger::OnServiceRequest,_pd_manager,std::placeholders::_1,std::placeholders::_2);
            _dispatcher->registerHandler<ServiceRequest>(MType::REQ_SERVICE,message_callback);
            

            _server=ServerFactory::create(port);
            _server->setMessageCallback(std::bind(&Dispatcher::dispatch, _dispatcher, std::placeholders::_1, std::placeholders::_2));
            _server->setCloseCallback(std::bind(&Rpc_Registry::OnConnShutdown, this, std::placeholders::_1));
        }
        void OnConnShutdown(const BaseConnection::ptr &conn)
        {
            _pd_manager->OnServiceShutdown(conn);
        }
        void start()
        {
            _server->start();
        }

        private:
            BaseServer::ptr _server;
            Rpc_Router::ptr _router;
            PDManger::ptr _pd_manager;
            Dispatcher::ptr _dispatcher;
        };

        //rpc服务端
        //1.用于提供rpc的服务端，可以设置是否启用服务注册，向服务中心注册对应的服务
        class Rpc_Server
        {
        public:
        //
        Rpc_Server(const Address &acess, const Address& provider, bool enable_register=false):
        _acess(acess),_dispatcher(DispatcherFactory::create()),_router(make_shared<Rpc_Router>()),_enable_register(enable_register)
        {
            //检查是否启用register
            if(enable_register)
            {
                _provider_client=std::make_shared<client::ProviderClient>(provider.first,provider.second);
            }
            auto message_callback=std::bind(&Rpc_Router::OnRpcRequest,_router,std::placeholders::_1,std::placeholders::_2);
            _dispatcher->registerHandler<RpcRequest>(MType::REQ_RPC,message_callback);
            
            _server=ServerFactory::create(acess.second);
            _server->setMessageCallback(std::bind(&Dispatcher::dispatch, _dispatcher, std::placeholders::_1, std::placeholders::_2));

            

        }
        void Register(const ServerDescribe::ptr &server)
        {
            if(_enable_register)
            {
                bool ret=_provider_client->RegistryClient(server->MethodName(),_acess);
                if(ret==false)
                    LOG(LogLevel::ERROR)<<"注册服务失败";
            }
            _router->Register(server);
        }
        void start()
        {
            _server->start();
        }
        private:
            bool _enable_register;
            Address _acess;
            client::ProviderClient::ptr _provider_client;
            Dispatcher::ptr _dispatcher;
            Rpc_Router::ptr _router;
            BaseServer::ptr _server;
        };

        class Rpc_Topic
        {
        public:
        Rpc_Topic(int port):_topic_manager(make_shared<TopicManager>()),_dispatcher(make_shared<Dispatcher>())
        {
            auto message_callback=std::bind(&TopicManager::OnTopicMessage,_topic_manager,std::placeholders::_1,std::placeholders::_2);
            _dispatcher->registerHandler<TopicRequest>(MType::REQ_TOPIC,message_callback);
            

            _server=ServerFactory::create(port);
            _server->setMessageCallback(std::bind(&Dispatcher::dispatch, _dispatcher, std::placeholders::_1, std::placeholders::_2));
            _server->setCloseCallback(std::bind(&Rpc_Topic::OnConnShutdown,this, std::placeholders::_1));
        }
        void OnConnShutdown(const BaseConnection::ptr &conn)
        {
            _topic_manager->OnShutdown(conn);
        }
        void start()
        {
            _server->start();
        }

        private:
            BaseServer::ptr _server;
            TopicManager::ptr _topic_manager;
            Dispatcher::ptr _dispatcher;
        };
    }
}